#include "DeviceWrap.h"

DeviceManager *g_manager = NULL;

#define SET_METHOD(name) \
  Nan::SetPrototypeMethod(tpl, #name, name)

NAN_MODULE_INIT(DeviceWrap::Init) {
  v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  SET_METHOD(on);
  SET_METHOD(getHandle);
  SET_METHOD(startReceivePlateResult);
  SET_METHOD(stopReceivePlateResult);
  SET_METHOD(startRealPlay);
  SET_METHOD(stopRealPlay);
  SET_METHOD(forceTrigger);
  SET_METHOD(queryCountByTimeAndPlate);
  SET_METHOD(queryPageRecordByTimeAndPlate);
  SET_METHOD(whiteListGetVehicleCount);
  SET_METHOD(whiteListLoadVehicle);
  SET_METHOD(whiteListImportRows);
  SET_METHOD(whiteListDeleteVehicleByID);
  SET_METHOD(getBoardType);
  SET_METHOD(getBoardVersion);
  SET_METHOD(getParamProperty);
  SET_METHOD(getVideoStreamParam);
  SET_METHOD(setVideoStreamParam);
  SET_METHOD(getVideoOsdParam);
  SET_METHOD(setVideoOsdParam);
  SET_METHOD(getVideoSourceParam);
  SET_METHOD(setVideoSourceParam);
  SET_METHOD(getEncryptParam);
  SET_METHOD(setEncryptParam);
  SET_METHOD(changeEncryptKey);
  SET_METHOD(resetEncryptKey);
  SET_METHOD(getNetworkParam);
  SET_METHOD(setNetworkParam);
  SET_METHOD(getSupportedProvinces);
  SET_METHOD(getVirtualLoopParam);
  SET_METHOD(getRegionOfInterestParam);
  SET_METHOD(getUserDefinedParam);
  SET_METHOD(getPlateRecognizeType);
  SET_METHOD(getPlateTriggerType);
  SET_METHOD(getSerialParam);
  SET_METHOD(setSerialParam);
  SET_METHOD(serialStart);
  SET_METHOD(serialStop);
  SET_METHOD(serialSend);
  SET_METHOD(getRS485PushParam);
  SET_METHOD(getOutputParam);
  SET_METHOD(getWLCheckMethod);
  SET_METHOD(getWLFuzzy);
  SET_METHOD(getNtpParam);
  SET_METHOD(reboot);
  SET_METHOD(isConnected);
  SET_METHOD(startUpdate);
  SET_METHOD(stopUpdate);
  SET_METHOD(getUpdateState);
  SET_METHOD(getUpdateProgress);
  SET_METHOD(getSoftwareVersion);
  SET_METHOD(restoreFullConfig);
  SET_METHOD(restorePartConfig);
  SET_METHOD(getGpioState);
  SET_METHOD(setGpioState);
  SET_METHOD(setGpioRecvCallback);
  SET_METHOD(setRequestTalk);
  SET_METHOD(getDateTime);
  SET_METHOD(setDateTime);
  SET_METHOD(getSerialNum);
  SET_METHOD(setUsrDefaultCfg);
  SET_METHOD(getUsrDefinedCfg);
  SET_METHOD(setUsrDefinedCfg);
  SET_METHOD(getEMS);
  SET_METHOD(tcpRecvStart);

  constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked());
}

void DeviceWrap::NewInstance(Nan::NAN_METHOD_ARGS_TYPE info, VzLPRClientHandle handle) {
  v8::Local<v8::Function> cons = Nan::New(constructor());
  const int argc = 1;
  v8::Local<v8::Value> argv[1] = { Nan::New(handle) };

  info.GetReturnValue().Set(Nan::NewInstance(cons, argc, argv).ToLocalChecked());
}

Device* DeviceWrap::get() {
  return device_;
}

VzLPRClientHandle DeviceWrap::take() {
  VzLPRClientHandle handle = device_->GetHandle();
  device_ = NULL;
  return handle;
}

DeviceWrap::DeviceWrap(Device *device)
  : device_(device) {

}

DeviceWrap::~DeviceWrap() {

}

Nan::Persistent<v8::Function>& DeviceWrap::constructor() {
  static Nan::Persistent<v8::Function> my_constructor;
  return my_constructor;
}

NAN_METHOD(DeviceWrap::New) {
  if (info.IsConstructCall()) {
    VzLPRClientHandle handle = info[0]->Int32Value();
    Device *device = g_manager->getDeviceByHandle(handle);
    DeviceWrap *obj = new DeviceWrap(device);
    obj->Wrap(info.This());
    info.GetReturnValue().Set(info.This());
  } else {
    const int argc = 1;
    v8::Local<v8::Value> argv[argc] = { info[0] };
    v8::Local<v8::Function> cons = Nan::New(constructor());
    info.GetReturnValue().Set(Nan::NewInstance(cons, argc, argv).ToLocalChecked());
  }
}

NAN_METHOD(DeviceWrap::on) {
  VERIFY_ON_ARGS();
  DeviceWrap* obj = ObjectWrap::Unwrap<DeviceWrap>(info.Holder());
  Nan::Utf8String p0(info[0]);
  v8::Local<v8::Function> p1 = v8::Local<v8::Function>::Cast(info[1]);
  std::string event = std::string(*p0);
  Nan::Callback *callback = new Nan::Callback(p1);

  obj->get()->on(event, callback);
  info.GetReturnValue().SetUndefined();
}

NAN_METHOD(DeviceWrap::getHandle) {
  DeviceWrap* obj = ObjectWrap::Unwrap<DeviceWrap>(info.Holder());
  VzLPRClientHandle handle = obj->get()->GetHandle();
  info.GetReturnValue().Set(Nan::New((int)handle));
}

NAN_METHOD(DeviceWrap::startReceivePlateResult) {
  RuleObject::Ptr rule = RuleObject::CreateBasicRule(BooleanType);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, startReceivePlateResult);
}

NAN_METHOD(DeviceWrap::stopReceivePlateResult) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, stopReceivePlateResult);
}

NAN_METHOD(DeviceWrap::startRealPlay) {
  RuleObject::Ptr rule = RuleObject::CreateBasicRule(IntType);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, startRealPlay);
}

NAN_METHOD(DeviceWrap::stopRealPlay) {
  RuleObject::Ptr rule = RuleObject::CreateBasicRule(IntType);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, stopRealPlay);
}

NAN_METHOD(DeviceWrap::forceTrigger) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, forceTrigger);
}

NAN_METHOD(DeviceWrap::queryCountByTimeAndPlate) {
  RuleObject::Ptr rule = RuleObject::CreateObjectRule();
  rule->AddBasicRule("startTime", StringType, true);
  rule->AddBasicRule("endTime", StringType, true);
  rule->AddBasicRule("keyword", StringType, true);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, queryCountByTimeAndPlate);
}

NAN_METHOD(DeviceWrap::queryPageRecordByTimeAndPlate) {
  RuleObject::Ptr rule = RuleObject::CreateObjectRule();
  rule->AddBasicRule("startTime", StringType, true);
  rule->AddBasicRule("endTime", StringType, true);
  rule->AddBasicRule("keyword", StringType, true);
  rule->AddBasicRule("startIndex", IntType, true);
  rule->AddBasicRule("endIndex", IntType, true);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, queryPageRecordByTimeAndPlate);
}

NAN_METHOD(DeviceWrap::whiteListGetVehicleCount) {
  RuleObject::Ptr rule = RuleObject::CreateObjectRule();
  rule->AddBasicRule("matchMode", StringType, true); // like/equal
  RuleObject::Ptr match_list_rule = rule->AddObjectArrayRule("matchList", true);
  match_list_rule->AddBasicRule("field", StringType, true);
  match_list_rule->AddBasicRule("keyword", StringType, true);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, whiteListGetVehicleCount);
}

NAN_METHOD(DeviceWrap::whiteListLoadVehicle) {
  RuleObject::Ptr rule = RuleObject::CreateObjectRule();
  rule->AddBasicRule("matchMode", StringType, true);
  RuleObject::Ptr match_list_rule = rule->AddObjectArrayRule("matchList", true);
  match_list_rule->AddBasicRule("field", StringType, true);
  match_list_rule->AddBasicRule("keyword", StringType, true);
  rule->AddBasicRule("limitType", StringType, true); // one/all/range
  rule->AddBasicRule("startIndex", IntType, false);
  rule->AddBasicRule("count", IntType, false);
  RuleObject::Ptr sort_rule = rule->AddObjectRule("sort", false);
  sort_rule->AddBasicRule("field", StringType, true);
  sort_rule->AddBasicRule("type", StringType, true); // desc/asc
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, whiteListLoadVehicle);
}

NAN_METHOD(DeviceWrap::whiteListImportRows) {
  RuleObject::Ptr rule = RuleObject::CreateObjectArrayRule();
  rule->AddBasicRule("plateId", StringType, true);
  rule->AddBasicRule("enabled", BooleanType, true);
  rule->AddBasicRule("effectTimeEnabled", BooleanType, true);
  rule->AddBasicRule("expireTimeEnabled", BooleanType, true);
  rule->AddBasicRule("effectTime", StringType, true);
  rule->AddBasicRule("expireTime", StringType, true);
  rule->AddBasicRule("alarmEnabled", BooleanType, true);
  rule->AddBasicRule("color", IntType, true);
  rule->AddBasicRule("plateType", IntType, true);
  rule->AddBasicRule("plateCode", StringType, true);
  rule->AddBasicRule("plateRemark", StringType, true);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, whiteListImportRows);
}

NAN_METHOD(DeviceWrap::whiteListDeleteVehicleByID) {
  RuleObject::Ptr rule = RuleObject::CreateBasicArrayRule(UintType);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, whiteListDeleteVehicleByID);
}

NAN_METHOD(DeviceWrap::getBoardType) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getBoardType);
}

NAN_METHOD(DeviceWrap::getBoardVersion) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getBoardVersion);
}

NAN_METHOD(DeviceWrap::getParamProperty) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getParamProperty);
}

NAN_METHOD(DeviceWrap::getVideoStreamParam) {
  RuleObject::Ptr rule = RuleObject::CreateBasicRule(IntType, false);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, getVideoStreamParam);
}

NAN_METHOD(DeviceWrap::setVideoStreamParam) {
  RuleObject::Ptr rule = RuleObject::CreateObjectRule();
  rule->AddBasicRule("streamIndex", IntType, false);
  rule->AddBasicRule("resolution", IntType, true);
  rule->AddBasicRule("frameRate", IntType, true);
  rule->AddBasicRule("encodeType", IntType, true);
  rule->AddBasicRule("streamType", IntType, true);
  rule->AddBasicRule("videoQuality", IntType, true);
  rule->AddBasicRule("bitRate", IntType, true);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, setVideoStreamParam);
}

NAN_METHOD(DeviceWrap::getVideoOsdParam) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getVideoOsdParam);
}

NAN_METHOD(DeviceWrap::setVideoOsdParam) {
  RuleObject::Ptr rule = RuleObject::CreateObjectRule();
  rule->AddBasicRule("dateEnabled", BooleanType, true);
  rule->AddBasicRule("dateFormat", IntType, true);
  rule->AddBasicRule("datePosX", IntType, true);
  rule->AddBasicRule("datePosY", IntType, true);
  rule->AddBasicRule("timeEnabled", BooleanType, true);
  rule->AddBasicRule("timeFormat", IntType, true);
  rule->AddBasicRule("timePosX", IntType, true);
  rule->AddBasicRule("timePosY", IntType, true);
  rule->AddBasicRule("textEnabled", BooleanType,  true);
  rule->AddBasicRule("textContent", StringType, true);
  rule->AddBasicRule("textPosX", IntType, true);
  rule->AddBasicRule("textPosY", IntType, true);
  rule->AddBasicRule("logoEnabled", BooleanType, false);
  rule->AddBasicRule("logoPosX", IntType, false);
  rule->AddBasicRule("logoPosY", IntType, false);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, setVideoOsdParam);
}

NAN_METHOD(DeviceWrap::getVideoSourceParam) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getVideoSourceParam);
}

NAN_METHOD(DeviceWrap::setVideoSourceParam) {
  RuleObject::Ptr rule = RuleObject::CreateObjectRule();
  rule->AddBasicRule("brightness", IntType, false);
  rule->AddBasicRule("contrast", IntType, false);
  rule->AddBasicRule("saturation", IntType, false);
  rule->AddBasicRule("sharpness", IntType, false);
  rule->AddBasicRule("maxGain", IntType, false);
  rule->AddBasicRule("exposureTime", IntType, false);
  rule->AddBasicRule("imageFlip", IntType, false);
  rule->AddBasicRule("denoiseMode", IntType, false);
  rule->AddBasicRule("denoiseIntensity", IntType, false);
  rule->AddBasicRule("frequency", IntType, false);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, setVideoSourceParam);
}

NAN_METHOD(DeviceWrap::getEncryptParam) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getEncryptParam);
}

NAN_METHOD(DeviceWrap::setEncryptParam) {
  RuleObject::Ptr rule = RuleObject::CreateObjectRule();
  rule->AddBasicRule("currentKey", StringType, true);
  rule->AddBasicRule("encryptId", UintType, true);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, setEncryptParam);
}

NAN_METHOD(DeviceWrap::changeEncryptKey) {
  RuleObject::Ptr rule = RuleObject::CreateObjectRule();
  rule->AddBasicRule("currentKey", StringType, true);
  rule->AddBasicRule("newKey", StringType, true);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, changeEncryptKey);
}

NAN_METHOD(DeviceWrap::resetEncryptKey) {
  RuleObject::Ptr rule = RuleObject::CreateObjectRule();
  rule->AddBasicRule("primeKey", StringType, true);
  rule->AddBasicRule("newKey", StringType, true);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, resetEncryptKey);
}

NAN_METHOD(DeviceWrap::getNetworkParam) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getNetworkParam);
}

NAN_METHOD(DeviceWrap::setNetworkParam) {
  RuleObject::Ptr rule = RuleObject::CreateObjectRule();
  rule->AddBasicRule("ip", StringType, true);
  rule->AddBasicRule("port", UintType, false);
  rule->AddBasicRule("netmask", StringType, true);
  rule->AddBasicRule("gateway", StringType, true);
  rule->AddBasicRule("dns", StringType, false);
  rule->AddBasicRule("SL", UintType, false);
  rule->AddBasicRule("SH", UintType, false);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, setNetworkParam);
}

NAN_METHOD(DeviceWrap::getSupportedProvinces) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getSupportedProvinces);
}


NAN_METHOD(DeviceWrap::getVirtualLoopParam) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getVirtualLoopParam);
}

NAN_METHOD(DeviceWrap::getRegionOfInterestParam) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getRegionOfInterestParam);
}

NAN_METHOD(DeviceWrap::getUserDefinedParam) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getUserDefinedParam);
}

NAN_METHOD(DeviceWrap::getPlateRecognizeType) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getPlateRecognizeType);
}

NAN_METHOD(DeviceWrap::getPlateTriggerType) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getPlateTriggerType);
}

NAN_METHOD(DeviceWrap::getSerialParam) {
  RuleObject::Ptr rule = RuleObject::CreateBasicRule(IntType);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, getSerialParam);
}

NAN_METHOD(DeviceWrap::setSerialParam) {
	RuleObject::Ptr rule = RuleObject::CreateObjectRule();

	rule->AddBasicRule("serialPort", IntType, true);
	rule->AddBasicRule("baudRate", IntType, false);
	rule->AddBasicRule("parityBit", IntType, false);
	rule->AddBasicRule("dataBit", IntType, false);
	rule->AddBasicRule("stopBit", IntType, false);
	
	ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, setSerialParam);
}

NAN_METHOD(DeviceWrap::serialStart) {
	RuleObject::Ptr rule = RuleObject::CreateBasicRule(IntType);
	ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, serialStart);
}

NAN_METHOD(DeviceWrap::serialStop) {
	RuleObject::Ptr rule = RuleObject::CreateBasicRule(IntType);
	ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, serialStop);
}

NAN_METHOD(DeviceWrap::serialSend) {
	RuleObject::Ptr rule = RuleObject::CreateObjectRule();

	rule->AddBasicRule("serialPort", IntType, true);
	rule->AddBasicRule("serialData", StringType, true);

	ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, serialSend);
}

NAN_METHOD(DeviceWrap::getRS485PushParam) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getRS485PushParam);
}

NAN_METHOD(DeviceWrap::getOutputParam) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getOutputParam);
}

NAN_METHOD(DeviceWrap::getWLCheckMethod) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getWLCheckMethod);
}

NAN_METHOD(DeviceWrap::getWLFuzzy) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getWLFuzzy);
}

NAN_METHOD(DeviceWrap::getNtpParam) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getNtpParam);
}

NAN_METHOD(DeviceWrap::reboot) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, reboot);
}

NAN_METHOD(DeviceWrap::isConnected) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, isConnected);
}

NAN_METHOD(DeviceWrap::startUpdate) {
  RuleObject::Ptr rule = RuleObject::CreateBasicRule(StringType);
  ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, startUpdate);
}

NAN_METHOD(DeviceWrap::stopUpdate) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, stopUpdate);
}

NAN_METHOD(DeviceWrap::getUpdateState) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getUpdateState);
}

NAN_METHOD(DeviceWrap::getUpdateProgress) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getUpdateProgress);
}

NAN_METHOD(DeviceWrap::getSoftwareVersion) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getSoftwareVersion);
}

NAN_METHOD(DeviceWrap::restoreFullConfig) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, restoreFullConfig);
}

NAN_METHOD(DeviceWrap::restorePartConfig) {
  RuleObject::Ptr rule;
  ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, restorePartConfig);
}

NAN_METHOD(DeviceWrap::getGpioState) {
	RuleObject::Ptr rule = RuleObject::CreateBasicRule(UintType, true);
	//rule->AddBasicRule("gpioChannel", UintType, true);
	ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, getGpioState);
}

NAN_METHOD(DeviceWrap::setGpioState) {
	RuleObject::Ptr rule = RuleObject::CreateObjectRule();

	//rule->AddBasicRule("type", StringType, true);
	rule->AddBasicRule("chnId", IntType, true);
	rule->AddBasicRule("value", IntType, false);
	rule->AddBasicRule("duration", IntType, false);

	ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, setGpioState);
}

NAN_METHOD(DeviceWrap::setGpioRecvCallback) {
	RuleObject::Ptr rule;

	ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, setGpioRecvCallback);
}

NAN_METHOD(DeviceWrap::setRequestTalk) {
	RuleObject::Ptr rule;

	ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, setRequestTalk);
}

NAN_METHOD(DeviceWrap::getDateTime) {
	RuleObject::Ptr rule;

	ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getDateTime);
}

NAN_METHOD(DeviceWrap::setDateTime) {
	RuleObject::Ptr rule = RuleObject::CreateObjectRule();

	rule->AddBasicRule("year", IntType, true);
	rule->AddBasicRule("month", IntType, true);
	rule->AddBasicRule("day", IntType, true);
	rule->AddBasicRule("hour", IntType, true);
	rule->AddBasicRule("min", IntType, true);
	rule->AddBasicRule("sec", IntType, true);

	ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, setDateTime);
}

NAN_METHOD(DeviceWrap::getSerialNo) {
	RuleObject::Ptr rule = RuleObject::CreateObjectRule();

	rule->AddBasicRule("ip", StringType, false);
	rule->AddBasicRule("port", UintType, false);

	ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, getSerialNo);
}

NAN_METHOD(DeviceWrap::getSerialNum) {
	RuleObject::Ptr rule = RuleObject::CreateObjectRule();

	ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getSerialNum);
}

NAN_METHOD(DeviceWrap::setUsrDefaultCfg) {
	RuleObject::Ptr rule;

	ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, setUsrDefaultCfg);
}

NAN_METHOD(DeviceWrap::getUsrDefinedCfg) {
	RuleObject::Ptr rule;

	ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getUsrDefinedCfg);
}

NAN_METHOD(DeviceWrap::setUsrDefinedCfg) {
	RuleObject::Ptr rule = RuleObject::CreateBasicRule(StringType, true);

	ASYNC_INVOKE_DEVICE(BIND_WITH_PARAM_WITH_RESULT, setUsrDefinedCfg);
}

NAN_METHOD(DeviceWrap::getEMS) {
	RuleObject::Ptr rule;

	ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, getEMS);
}

NAN_METHOD(DeviceWrap::tcpRecvStart) {
	RuleObject::Ptr rule;

	ASYNC_INVOKE_DEVICE(BIND_NO_PARAM_WITH_RESULT, tcpRecvStart);
}
